using System;
using System.Windows;
using System.Windows.Controls;
using System.Data;
using System.Xml;
using System.Configuration;
using System.Threading;
using System.Diagnostics;
using System.Configuration;
using System.Globalization;
using System.Collections.Generic;

using MVExplorer.Components;
using MeetCommon.Service;

namespace MVExplorer
{

	public partial class App : System.Windows.Application
	{
		private MVELogon logon;
		private MVESettings appSettings = new MVESettings();
		private MeetCommon.Service.MeetServerConnector connector = new MeetCommon.Service.MeetServerConnector();

		public App()
			: base()
		{
            string cultureString = string.Empty;
            try
            {
                cultureString = ConfigurationManager.AppSettings["UICulture"];
            }
            catch (ConfigurationErrorsException e)
            {
                System.Diagnostics.Debug.WriteLine(e.Message);
            }
            if (!string.IsNullOrEmpty(cultureString))
            {
                Thread.CurrentThread.CurrentUICulture = new CultureInfo(cultureString);
                Thread.CurrentThread.CurrentCulture = new CultureInfo(cultureString);
            }
			this.Startup += new StartupEventHandler(App_Startup);
			this.Dispatcher.UnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(Dispatcher_UnhandledException);
			AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
		}

		void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
		{
#if !DEBUG
			MessageBox.Show("Aborting due to exception: " + (e.ExceptionObject as Exception).Message, "MVExplorer - AppDomain Error");
#endif
        }

		void Dispatcher_UnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
		{
#if !DEBUG
			e.Handled = true;
			MessageBox.Show("Aborting due to exception: " + (e.Exception as Exception).Message, "MVExplorer - Application Error");
			this.MainWindow.Close();
#endif
        }

		void App_Startup(object sender, StartupEventArgs e)
		{
			logon = new MVELogon();

			logon.UserName = appSettings.GetText("UserName");
			logon.LogonExecuted += new EventHandler(logon_LogonExecuted);
			logon.LogonCancelled += new EventHandler(logon_LogonCancelled);
			logon.FadeOuted += new EventHandler(logon_FadeOuted);
			logon.Show();
		}

#if DEBUG
		private void ShowWithoutLogon()
		{
			this.MainWindow = new MVEMain();
			MVEMain main = this.MainWindow as MVEMain;
			//connector.UserID = 1;
			main.ServerConnector = connector;
			this.MainWindow.ContentRendered += new EventHandler(MainWindow_ContentRendered);
			main.Show();
		}
#endif

		private bool fCanceled = false;
		void logon_LogonCancelled(object sender, EventArgs e)
		{
			fCanceled = true;
			logon.FadeOut();
		}

		void logon_FadeOuted(object sender, EventArgs e)
		{
			if (fCanceled)
			{
				this.Shutdown();
				return;
			}
			MVEMain main = this.MainWindow as MVEMain;
			Debug.Assert(main != null);
			main.Show();
			main.ServerConnector = connector;

			main.KeywordDocument = connector.QueryKeywords();

		}

		#region Logon Methods

		void logon_LogonExecuted(object sender, EventArgs e)
		{
			if (logon.UserName == "")
			{
				appSettings.SetText("UserName", "");
				return;
			}
			Logon();

		}

		private delegate void NoArgDelegate();
		private delegate void OneArgDelegate(string arg);
		private delegate void TwoArgDelegate(string arg1, string arg2, object args);

		private void Logon()
		{
			TwoArgDelegate fetcher = new TwoArgDelegate(this.LogonThread);

			logon.EnableUI = false;
            Dictionary<string, string> _params = new Dictionary<string, string>();
            _params.Add("LogonProcessing", Application.Current.Resources["LogonProcessing"] as String);
            _params.Add("InvalidCredential", Application.Current.Resources["InvalidCredential"] as String);
            _params.Add("NetworkFailure", Application.Current.Resources["NetworkFailure"] as String);
            _params.Add("UpdateLogonMessage", Application.Current.Resources["UpdateLogonMessage"] as String);
			fetcher.BeginInvoke(logon.UserName, logon.Password, _params, null, null);
		}

		private void LogonThread(string username, string password, Object args)
		{
			try
			{
                Dictionary<string, string> dict = args as Dictionary<string, string>;
                string message = dict["LogonProcessing"];
				this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new OneArgDelegate(UpdateLogonMessage), message);

				if (connector.Logon(username, password))
				{
					Debug.WriteLine("Logon successful.");
					appSettings.SetText("UserName", username);

                    this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new OneArgDelegate(this.LogonComplete), dict["UpdateLogonMessage"]);
					this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new NoArgDelegate(this.LoadMain));
				}
				else
				{
                    message = dict["InvalidCredential"];
                    this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new OneArgDelegate(LogonFailed), message);
				}
			}
			catch (MeetCommon.Service.MVENetworkOperationException ex)
			{
                string message = ex.Message;//dict["NetworkFailure"];
                this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new OneArgDelegate(LogonFailed), message);
				Debug.WriteLine(ex.Message);
			}

		}

		private void CloseLogon()
		{
			logon.FadeOut();
		}

		private void LogonComplete(string message)
		{
			UpdateLogonMessage(message);
			CloseLogon();
		}

		private void LogonFailed(string message)
		{
			UpdateLogonMessage(message);
			logon.EnableUI = true;
		}

		private void UpdateLogonMessage(string message)
		{
			logon.Message = message;
		}

		private void LoadMain()
		{
			Debug.WriteLine("Loading MainWindow... ");
			this.MainWindow = new MVEMain();
			this.MainWindow.ContentRendered += new EventHandler(MainWindow_ContentRendered);
		}
		#endregion

		void MainWindow_ContentRendered(object sender, EventArgs e)
		{
		}
	}
}